//
//  QRCodeScannerView.swift
//  CMB250716
//
//  Created by Andy Lau on 18/7/25.
//

import Foundation
import SwiftUI
import AVFoundation
import AudioToolbox

struct QRCodeScannerView: UIViewControllerRepresentable {
    @Binding var scannedCode: String?
    @Environment(\.presentationMode) var presentationMode
    
    func makeUIViewController(context: Context) -> QRScannerViewController {
        let controller = QRScannerViewController()
        controller.delegate = context.coordinator
        return controller
    }
    
    func updateUIViewController(_ uiViewController: QRScannerViewController, context: Context) {
        // No updates needed
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, QRScannerDelegate {
        let parent: QRCodeScannerView
        
        init(_ parent: QRCodeScannerView) {
            self.parent = parent
        }
        
        func didScanQRCode(_ code: String) {
            // 调试日志：记录实际扫描到的二维码内容
            print("\n🔍 [QR调试] 扫描到的原始内容: \(code)")
            
            // 解析桌号并记录结果
            let parsedTableNumber = QRScannerConfig.parseTableNumber(from: code)
            print("📊 [QR调试] 解析后的桌号: \(parsedTableNumber)")
            
            // 添加延迟以确保扫描稳定性
            DispatchQueue.main.asyncAfter(deadline: .now() + QRScannerConfig.Scanning.successDelay) {
                // 传递解析后的桌号而不是原始内容
                self.parent.scannedCode = parsedTableNumber
                NotificationCenter.default.post(name: .init(QRScannerConfig.Notifications.qrCodeScannedNotification), object: parsedTableNumber)
                self.parent.presentationMode.wrappedValue.dismiss()
            }
        }
        
        func didFailToScan() {
            self.parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

protocol QRScannerDelegate: AnyObject {
    func didScanQRCode(_ code: String)
    func didFailToScan()
}

class QRScannerViewController: UIViewController {
    weak var delegate: QRScannerDelegate?
    private var captureSession: AVCaptureSession!
    private var previewLayer: AVCaptureVideoPreviewLayer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        checkCameraPermission()
    }
    
    private func checkCameraPermission() {
        switch AVCaptureDevice.authorizationStatus(for: .video) {
        case .authorized:
            setupCamera()
            setupUI()
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
                DispatchQueue.main.async {
                    if granted {
                        self?.setupCamera()
                        self?.setupUI()
                    } else {
                        self?.delegate?.didFailToScan()
                    }
                }
            }
        case .denied, .restricted:
            delegate?.didFailToScan()
        @unknown default:
            delegate?.didFailToScan()
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if !captureSession.isRunning {
            DispatchQueue.global(qos: .background).async {
                self.captureSession.startRunning()
            }
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if captureSession.isRunning {
            captureSession.stopRunning()
        }
    }
    
    private func setupCamera() {
        captureSession = AVCaptureSession()
        
        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else {
            delegate?.didFailToScan()
            return
        }
        
        // 配置相机对焦和曝光设置
        do {
            try videoCaptureDevice.lockForConfiguration()
            
            // 设置对焦模式
            if videoCaptureDevice.isFocusModeSupported(QRScannerConfig.Camera.focusMode) {
                videoCaptureDevice.focusMode = QRScannerConfig.Camera.focusMode
            }
            
            // 设置曝光模式
            if videoCaptureDevice.isExposureModeSupported(QRScannerConfig.Camera.exposureMode) {
                videoCaptureDevice.exposureMode = QRScannerConfig.Camera.exposureMode
            }
            
            // 设置白平衡模式
            if videoCaptureDevice.isWhiteBalanceModeSupported(QRScannerConfig.Camera.whiteBalanceMode) {
                videoCaptureDevice.whiteBalanceMode = QRScannerConfig.Camera.whiteBalanceMode
            }
            
            // 启用平滑自动对焦（如果支持）
            if QRScannerConfig.Camera.enableSmoothAutoFocus && videoCaptureDevice.isSmoothAutoFocusSupported {
                videoCaptureDevice.isSmoothAutoFocusEnabled = true
            }
            
            videoCaptureDevice.unlockForConfiguration()
        } catch {
            // 相机配置失败
        }
        
        let videoInput: AVCaptureDeviceInput
        
        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            delegate?.didFailToScan()
            return
        }
        
        if captureSession.canAddInput(videoInput) {
            captureSession.addInput(videoInput)
        } else {
            delegate?.didFailToScan()
            return
        }
        
        let metadataOutput = AVCaptureMetadataOutput()
        
        if captureSession.canAddOutput(metadataOutput) {
            captureSession.addOutput(metadataOutput)
            
            metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            metadataOutput.metadataObjectTypes = [.qr]
        } else {
            delegate?.didFailToScan()
            return
        }
        
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        view.layer.addSublayer(previewLayer)
    }
    
    private func setupUI() {
        view.backgroundColor = UIColor.black
        
        // 添加扫描框
        let scanFrame = UIView()
        scanFrame.layer.borderColor = UIColor.white.cgColor
        scanFrame.layer.borderWidth = QRScannerConfig.UI.scanFrameBorderWidth
        scanFrame.layer.cornerRadius = QRScannerConfig.UI.scanFrameCornerRadius
        scanFrame.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(scanFrame)
        
        // 添加提示标签
        let instructionLabel = UILabel()
        instructionLabel.text = QRScannerConfig.UI.instructionText
        instructionLabel.textColor = UIColor.white
        instructionLabel.textAlignment = .center
        instructionLabel.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        instructionLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(instructionLabel)
        
        // 添加取消按钮
        let cancelButton = UIButton(type: .system)
        cancelButton.setTitle(QRScannerConfig.UI.cancelButtonText, for: .normal)
        cancelButton.setTitleColor(UIColor.white, for: .normal)
        cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        cancelButton.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        cancelButton.layer.cornerRadius = 8
        cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
        cancelButton.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(cancelButton)
        
        NSLayoutConstraint.activate([
            // 扫描框约束
            scanFrame.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            scanFrame.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -50),
            scanFrame.widthAnchor.constraint(equalToConstant: QRScannerConfig.UI.scanFrameSize),
            scanFrame.heightAnchor.constraint(equalToConstant: QRScannerConfig.UI.scanFrameSize),
            
            // 提示标签约束
            instructionLabel.topAnchor.constraint(equalTo: scanFrame.bottomAnchor, constant: 30),
            instructionLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            instructionLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 20),
            instructionLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -20),
            
            // 取消按钮约束
            cancelButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            cancelButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            cancelButton.widthAnchor.constraint(equalToConstant: 60),
            cancelButton.heightAnchor.constraint(equalToConstant: 40)
        ])
    }
    
    @objc private func cancelTapped() {
        delegate?.didFailToScan()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        previewLayer?.frame = view.layer.bounds
    }
}

extension QRScannerViewController: AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            guard let stringValue = readableObject.stringValue else { return }
            
            // 添加反馈
            if QRScannerConfig.Scanning.enableHapticFeedback {
                AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            }
            
            delegate?.didScanQRCode(stringValue)
        }
    }
}